﻿using System;
using NUnit.Framework;
/*
namespace MockFramework.Tests
{
    [TestFixture]
    public class MockFixture
    {
        /// <summary>
        /// Tests
        /// </summary>

        [Test]
        public void MockOfAbstractClass()
        {
            var mock = new Mock<FooAbstract>();
            // setup - expectations
            mock.Setup(x => x.Check("foo")).Returns(false);
            mock.Setup(x => x.ToString()).Returns("MyFoo");
            // verify
            Assert.False(mock.Object.Check("foo"));
            Assert.AreEqual("MyFoo", mock.Object.ToString());
            Assert.Throws<NotSupportedException>(() => mock.Object.Check("bar"));
        }
        
        [Test]
		public void CreatesMockAndExposesInterface()
		{
			var mock = new Mock<IComparable>();
			IComparable comparable = mock.Object;
			Assert.NotNull(comparable);
		}

        [Test]
        public void CallsUnderlyingClassEquals()
        {
            var mock = new Mock<FooOverrideEquals>();
            var mock2 = new Mock<FooOverrideEquals>();
            mock.Object.Name = "Foo";
            mock2.Object.Name = "Foo";
            Assert.True(mock.Object.Equals(mock2.Object));
        }

        [Test]
        public void CallsUnderlyingClassToString()
        {
            var mock = new Mock<FooOverrideToString>();
            var mock2 = new Mock<FooOverrideToString>();
            mock.Object.Name = "Foo";
            mock2.Object.Name = "DifferentFoo";
            Console.WriteLine(mock.Object.ToString());
            Console.WriteLine(mock2.Object.ToString());
        }

        [Test]
        public void FillingRemovesInventoryIfInStock()
        {
            // setup - data
            var order = new Order("Orange", 50);
            var mock = new Mock<IWarehouse>();
            // setup - expectations
            mock.Setup(x => x.HasInventory("Orange", 50)).Returns(true);
            // exercise
            order.Fill(mock.Object);
            // verify state
            Assert.True(order.IsFilled);
        }

        [Test]
        public void FillingDoesNotRemoveIfNotEnoughInStock()
        {
            // setup - data
            var order = new Order("Orange", 50);
            var mock = new Mock<IWarehouse>();

            // setup - expectations
            mock.Setup(x => x.HasInventory("Orange", 50)).Returns(false);
            mock.Setup(x => x.Remove("Orange", 50)).Throws(new InvalidOperationException());

            // exercise
            order.Fill(mock.Object);

            // verify
            Assert.False(order.IsFilled);
        }
        [Test]
        public void OverridesBehaviorFromAbstractClass()
        {
            var mock = new Mock<FooBase>();
            // setup - expectations
            mock.Setup(x => x.Check("foo")).Returns(false);
            // verify
            Assert.False(mock.Object.Check("foo"));
            Assert.True(mock.Object.Check("bar"));
        }

        [Test]
        public void OverridesObjectMethods()
        {
            var mock = new Mock<IEmpty>();
            mock.Setup(x => x.GetHashCode()).Returns(1);
            mock.Setup(x => x.ToString()).Returns("foo");
            mock.Setup(x => x.Equals(null)).Returns(true);

            Assert.AreEqual("foo", mock.Object.ToString());
            Assert.AreEqual(1, mock.Object.GetHashCode());
            Assert.True(mock.Object.Equals(null));
        }

        [Test]
        public void CallParameterCanBeVariable()
        {
            int value = 5;
            var mock = new Mock<IFoo>();

            mock.Setup(x => x.Echo(value)).Returns(() => value * 2);

            Assert.AreEqual(value * 2, mock.Object.Echo(value));
        }

       [Test]
        public void CallParameterCanBeMethodCall()
        {
            int value = 5;
            var mock = new Mock<IFoo>();

            mock.Setup(x => x.Echo(GetValue(value))).Returns(() => value * 2);

            Assert.AreEqual(value * 2, mock.Object.Echo(value * 2));
        }

        private int GetValue(int value)
        {
            return value * 2;
        }

        [Test]
        public void ExpectsVoidCall()
        {
            var mock = new Mock<IFoo>();

            mock.Setup(x => x.Submit());

            mock.Object.Submit();
        }

        [Test]
        public void ThrowsIfExpectationThrows()
        {
            var mock = new Mock<IFoo>();

            mock.Setup(x => x.Submit()).Throws(new FormatException());

            Assert.Throws<FormatException>(() => mock.Object.Submit());
        }

        [Test]
        public void MockObjectIsAssignableToMockedInterface()
        {
            var mock = new Mock<IFoo>();
            Assert.True(typeof(IFoo).IsAssignableFrom(mock.Object.GetType()));
        }

        [Test]
        public void MockObjectsEqualityIsReferenceEquals()
        {
            var mock1 = new Mock<IFoo>();
            var mock2 = new Mock<IFoo>();

            Assert.True(mock1.Object.Equals(mock1.Object));
            Assert.False(mock1.Object.Equals(mock2.Object));
        }

        [Test]
        public void HashCodeIsDifferentForEachMock()
        {
            var mock1 = new Mock<IFoo>();
            var mock2 = new Mock<IFoo>();

            Assert.AreEqual(mock1.Object.GetHashCode(), mock1.Object.GetHashCode());
            Assert.AreEqual(mock2.Object.GetHashCode(), mock2.Object.GetHashCode());
            Assert.AreNotEqual(mock1.Object.GetHashCode(), mock2.Object.GetHashCode());
        }

        [Test]
        public void ToStringIsNullOrEmpty()
        {
            var mock = new Mock<IFoo>();
            Assert.False(String.IsNullOrEmpty(mock.Object.ToString()));
        }

        [Test]
        public void ThrowsIfSealedClass()
        {
            Assert.Throws<NotSupportedException>(() => new Mock<FooSealed>());
        }

        [Test]
        public void ThrowsIfExpectOnNonVirtual()
        {
            var mock = new Mock<FooBase>();

            Assert.Throws<NotSupportedException>(() => mock.Setup(x => x.True()).Returns(false));
        }

        [Test]
        public void OverridesPreviousExpectation()
        {
            var mock = new Mock<IFoo>();

            mock.Setup(x => x.Echo(1)).Returns(5);

            Assert.AreEqual(5, mock.Object.Echo(1));

            mock.Setup(x => x.Echo(1)).Returns(10);

            Assert.AreEqual(10, mock.Object.Echo(1));
        }

        [Test]
        public void ConstructsObjectsWithCtorArguments()
        {
            var mock = new Mock<FooWithConstructors>("Hello", 26);

            Assert.AreEqual("Hello", mock.Object.StringValue);
            Assert.AreEqual(26, mock.Object.IntValue);

            // Should also construct without args.
            mock = new Mock<FooWithConstructors>();

            Assert.AreEqual(null, mock.Object.StringValue);
            Assert.AreEqual(0, mock.Object.IntValue);
        }

        [Test]
        public void ConstructsClassWithNoDefaultConstructor()
        {
            var mock = new Mock<ClassWithNoDefaultConstructor>("Hello", 26);

            Assert.AreEqual("Hello", mock.Object.StringValue);
            Assert.AreEqual(26, mock.Object.IntValue);
        }

        [Test]
        public void ConstructsClassWithNoDefaultConstructorAndNullValue()
        {
            var mock = new Mock<ClassWithNoDefaultConstructor>(null, 26);

            Assert.AreEqual(null, mock.Object.StringValue);
            Assert.AreEqual(26, mock.Object.IntValue);
        }

        [Test]
        public void ThrowsIfNoMatchingConstructorFound()
        {
            Assert.Throws<ArgumentException>(() =>
            {
                Console.WriteLine(new Mock<ClassWithNoDefaultConstructor>(25, true).Object);
            });
        }

        public abstract class FooAbstract
        {
            public abstract void Do(int value);
            public abstract bool Check(string value);
        }

        public abstract class FooOverrideEquals
        {
            public string Name { get; set; }

            public override bool Equals(object obj)
            {
                return (obj is FooOverrideEquals) &&
                    ((FooOverrideEquals)obj).Name == this.Name;
            }
            public override int GetHashCode()
            {
                return Name.GetHashCode();
            }
        }

        public class FooOverrideToString : FooOverrideEquals
        {
            public override String ToString()
            {
                return "FooOverrideToString: " + Name;
            }
        }

        public interface IWarehouse
        {
            bool HasInventory(string productName, int quantity);
            void Remove(string productName, int quantity);
        }
        public class Order
        {
            public string ProductName { get; private set; }
            public int Quantity { get; private set; }
            public bool IsFilled { get; private set; }

            public Order(string productName, int quantity)
            {
                this.ProductName = productName;
                this.Quantity = quantity;
            }
            public void Fill(IWarehouse warehouse)
            {
                if (warehouse.HasInventory(ProductName, Quantity))
                {
                    warehouse.Remove(ProductName, Quantity);
                    IsFilled = true;
                }
            }
        }

        public abstract class FooBase
        {
            public int ValueField;
            public abstract void Do(int value);

            public virtual bool Check(string value)
            {
                return true;
            }
            public bool GetIsProtected()
            {
                return IsProtected();
            }
            protected virtual bool IsProtected()
            {
                return true;
            }
            public bool True()
            {
                return true;
            }
            public bool BaseCalled = false;

            public virtual void BaseCall()
            {
                BaseCalled = true;
            }
            //public virtual string Generic<T>(T t)
            //{
            //    return t.GetType().ToString();
            //}

            public bool BaseReturnCalled = false;

            public virtual bool BaseCall(string value)
            {
                BaseReturnCalled = true;
                return default(bool);
            }
        }

        public interface IEmpty
        {
        }

        public sealed class FooSealed { }

        public class FooWithPrivateSetter
        {
            public virtual string Foo { get; private set; }
        }

        public class ClassWithNoDefaultConstructor
        {
            public ClassWithNoDefaultConstructor(string stringValue, int intValue)
            {
                this.StringValue = stringValue;
                this.IntValue = intValue;
            }

            public string StringValue { get; set; }
            public int IntValue { get; set; }
        }

        public abstract class FooWithConstructors
        {
            public FooWithConstructors(string stringValue, int intValue)
            {
                this.StringValue = stringValue;
                this.IntValue = intValue;
            }

            public FooWithConstructors()
            {
            }

            public override string ToString()
            {
                return base.ToString();
            }

            public string StringValue { get; set; }
            public int IntValue { get; set; }
        }

        public interface IFoo
        {
            int Echo(int value);
            void Submit();
        }
    }

}
*/